package com.bang.study.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @Auther: Bang
 * @Date: 2020/8/5 21:35
 * @Description:
 * <p>
 *     bean的生命后期
 *     1. 构造方法
 *     2. @PostConstruct ---> CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
 *     3. InitializingBean.afterPropertiesSet 方法
 *     4. @Bean(initMethod="initAnnotation") initMethod方法执行
 *
 *     5.  @PreDestroy  ---> CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
 *     6. DisposableBean.destroy 方法
 *     7. @Bean(destroyMethod = "destroyAnnotation") destroyMethod方法
 *
 *     关键代码:
 *     (1)、applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 *     (2)、invokeInitMethods(beanName, wrappedBean, mbd);
 *          (2.1) ((InitializingBean) bean).afterPropertiesSet();
 *          (2.2) invokeCustomInitMethod(beanName, bean, mbd); 即initMethod
 *     (3)、InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata.invokeDestroyMethods()
 *     (4)、((DisposableBean) this.bean).destroy();
 *     (5)、DisposableBeanAdapter.invokeCustomDestroyMethod()
 * </p>
 */
public class BeanLife implements InitializingBean, BeanPostProcessor, DisposableBean {

    public BeanLife() {
        System.err.println("BeanLife 无参构造");
    }

    /**
     * <p>
     *     CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
     *     这个BeanPostProcessor处理  @PostConstruct和 @PreDestroy注解
     * </p>
     */
    @PostConstruct
    public void initMethod() {
        System.err.println("BeanLife.......PostConstruct");
    }

    public void initAnnotation() {
        System.err.println("BeanLife.......initAnnotation");
    }

    public void destroyAnnotation() {
        System.err.println("BeanLife.......destroyAnnotation");
    }

    @PreDestroy
    public void preDestroy() {
        System.err.println("BeanLife.......preDestroy");
    }

    public void afterPropertiesSet() throws Exception {
        System.err.println("BeanLife...(InitializingBean)..afterPropertiesSet");
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.err.println("BeanLife.....postProcessBeforeInitialization " + beanName + " " + bean);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.err.println("BeanLife.....postProcessAfterInitialization " + beanName + " " + bean);
        return bean;
    }

    public void destroy() throws Exception {
        System.err.println("BeanLife...(DisposableBean)..destroy ");
    }
}
